<?php

namespace common\behavior\CommonMessagePushing;

use common\model\OriginalPlanNodeModel;
use common\model\TaskRelationModel;
use common\service\BehaviorService;
use common\service\ProjectService;
use think\Exception;
use Webman\Stomp\Client;

/**
 * 交付节点按时交付、延期 消息通知
 */
class OriginNodeReachingBehavior
{
    /**
     * @param $params
     * @return void
     * @throws Exception
     */
    public function run($params)
    {
        /***********  预处理开始  ************/
        $params = BehaviorService::getInstance()->dealParam(
            $params,
            [
                'node_id' => 'split_array|array_map,intval',
            ],
            [
                'node_id' => []
            ],
            'data',
            ['type' => 'update_origin_node_task_list'],
        );
        /***********  行为判断  ************/
        if ($params === false) {
            return;
        }
        /***********  变量迁移  ************/
        list($nodeIdList) = $params;
        if (empty($nodeIdList)) {
            return;
        }
        /***********  预处理结束  ************/

        /***********  消息预打包，传送至处理队列  ************/
        $originPlanNodeList = model(OriginalPlanNodeModel::class)
            ->where([
                'id' => ['in', implode(',', $nodeIdList)],
                'status' => 2,
            ])
            ->select();
        if (empty($originPlanNodeList)) {
            return;
        }
        // 合并 同 项目、关联id、环节 节点
        $uniqueRefKeyList = [
            'type',
            'link_id',
            'step_category_id',
            'name',
            'delivery_time',
            'project_id',
        ];
        $originPlanNodeMap = [];
        foreach ($originPlanNodeList as $nodeItem) {
            $taskSet = [
                'all' => explode(',', $nodeItem['all_task_ids']),
                'delivery' => explode(',', $nodeItem['delivery_task_ids']),
                'deprecated' => explode(',', $nodeItem['deprecated_task_ids'])
            ];
            $taskActive = array_diff($taskSet['all'], $taskSet['deprecated']);
            // 检查节点任务列表，节点任务为空/全部废除 的丢弃
            if (empty($taskSet['all']) || empty($taskActive)) {
                continue;
            }
            $uniqueInfo = array_filter($nodeItem, fn($k) => in_array($k, $uniqueRefKeyList), ARRAY_FILTER_USE_KEY);
            $uniqueKey = implode('#', $uniqueInfo);
            if (!isset($originPlanNodeMap[$uniqueKey])) {
                $originPlanNodeMap[$uniqueKey] = array_merge($taskSet, $uniqueInfo, ['id' => $nodeItem['id']]);
            } else {
                foreach ($taskSet as $key => $val) {
                    $originPlanNodeMap[$uniqueKey][$key] = array_push($originPlanNodeMap[$uniqueKey][$key], ...$val);
                }
            }
        }
//        $originPlanNodeOnTimeList = array_map($originPlanNodeMap, fn($item) => empty(array_diff($item['all'], $item['delivery'], $item['deprecated'])));
        $notifyRoleList = ['step_producer'];
        foreach ($originPlanNodeMap as $item) {
            // 全部交付： 全量 - 已废除 - 已交付 = []
            $nodeAllDelivered = empty(array_diff($item['all'], $item['delivery'], $item['deprecated']));
            // 取得下游环节
            $downstreamTaskIdList = model(TaskRelationModel::class)
                ->join('task on task_relation.source_task_id = task.id', 'left')
                ->where('find_in_set(task_relation.target_task_id, "' . implode(',', $item['all']) . '")')
                ->field('distinct task.step_category_id')
                ->select();
            $stepCategoryNotify = array_column($downstreamTaskIdList, 'step_category_id');
            // 处理接收人
            $receiver = [];
            $receiverCc = [];
            if (empty($receiver)) {
                $projectReceiverConfig = ProjectService::getInstance()->projectConfigMessageReceiverFind([
                    'project_id' => $item['project_id'],
                    'step_category_id' => $stepCategoryNotify,
                    'role_code_list' => $notifyRoleList
                ]);
                $projectReceiverConfig = array_merge(...array_column($projectReceiverConfig, 'message_receiver_list', 'id'));
                foreach ($projectReceiverConfig as $userGroup) {
                    foreach ($userGroup['user_list'] as $user) {
                        $receiver[] = [
                            'role' => $userGroup['role'],
                            'user_id' => $user,
                        ];
                    }
                }
            }
            $data = [
                'node_all_delivered' => $nodeAllDelivered,
                'source_id' => $item['id'],
                'source_module_code' => 'original_plan_node',
                'category' => 'original_plan_node_delivery',
                'receiver' => $receiver,
                'receiver_cc' => $receiverCc,
            ];
            try {
                trace("common node on time push behavior" . request()->getUnionUserId(), 'DEBUG');
                Client::send('common_message_pushing', build_queue_data_with_xu($data));
            } catch (\Throwable $e) {
                trace(format_exception_info($e), 'ERR');
            }
        }
        /***********  操作结束  ************/
        return;
    }
}
